/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package com.Spring.DAO;

import com.Spring.DAO.exceptions.NonexistentEntityException;
import com.Spring.DAO.exceptions.PreexistingEntityException;
import com.Spring.Model.Alumno;
import java.io.Serializable;
import java.util.List;
import javax.persistence.*;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Root;

/*
 *
 * @author Schwanstei
 */
public class AlumnoDAO implements Serializable {

    private EntityManager em;//Se declaro "em",una variable de tipo EntityManager
    // EntityManager es utilizada para la persistencia de aplicaciones en Java.
    public EntityManager getEntityManager() { //Se crea un método que consigue una instancia del EntityManager
        EntityManagerFactory emf = Persistence.createEntityManagerFactory("ABCPU");//Se obtiene  una instancia del Entity manager,indicando también el nombre de la PU
        EntityManager em=emf.createEntityManager(); //Se crea el EntityManager
        return em;
    }
    //Cada EntityMutilizanager puede realizar operaciones CRUD (Create, Read, Update, Delete)
    public void create(Alumno alumno) throws PreexistingEntityException, Exception { //Se crea un método que crea una instancia en la entidad alumno
        //EntityManager em = null;
        try {
            em = getEntityManager();// Se consigue el EntityManager
            em.getTransaction().begin();//Inicia una transancción. Se inicia interacción con BD
            em.persist(alumno);//Se persiste(guarda) el objeto de alumno del tipo Alumno
            em.getTransaction().commit();//Se termina la transacción. Se termina la interración con BD
        } catch (Exception ex) { //Exepción utilizada en caso de que el alumno a crear ya exista
            if (read(alumno.getNoCuenta()) != null) {
                throw new PreexistingEntityException("Alumno " + alumno + " already exists.", ex);
            }
            throw ex;
        } finally {
            if (em != null) {
                em.close();
            }
        }
    }
    
      public Alumno read(Integer id) {//Método para leer de una entidad
        em = getEntityManager();//Se accede al entity m
        try {
            return em.find(Alumno.class, id);
        } finally {
            em.close();
        }
    }
    public void update(Alumno alumno) throws NonexistentEntityException, Exception {// Método para actualizar el registro de la Entidad Alumno
        //EntityManager em = null;
        try {
            em = getEntityManager();//Se obtiene el EntityManager creado
            em.getTransaction().begin();
            alumno = em.merge(alumno);//Con merge se actulizan los datos del objeto recibido en el método en la BD
            em.getTransaction().commit();
        } catch (Exception ex) {//Se verifica que el alumno exista en la BD
            String msg = ex.getLocalizedMessage();
            if (msg == null || msg.length() == 0) {
                Integer id = alumno.getNoCuenta();
                if (read(id) == null) {//Mensaje a mostra en caso de que nos exista en alumno.
                    throw new NonexistentEntityException("The alumno with id " + id + " no longer exists.");
                }
            }
            throw ex;
        } finally {
            if (em != null) {//Si el alumno existe se termina el método con la actualización.
                em.close();
            }
        }
    }

    public void delete(Integer id) throws NonexistentEntityException {//Método que se encarga de eliminar cierto registro en la BD. Recibe el id del registro a eliminar
        //EntityManager em = null;
        try {
            em = getEntityManager();
            em.getTransaction().begin();
            Alumno alumno;//Se crea una objeto de tipo alumno
            try {//Se verifica que objeto de tipo alumno a eliminar exista.
                alumno = em.getReference(Alumno.class, id);
                alumno.getNoCuenta();
            } catch (EntityNotFoundException enfe) {//Si no existe el se envía el siguiente mensaje.
                throw new NonexistentEntityException("The alumno with id " + id + " no longer exists.", enfe);
            }
            em.remove(alumno);//En caso de existir, el registro de elimina con el método remove, enviando el objeto de tipo alumno creado
            em.getTransaction().commit();//Se termina la trasacción con la BD
        } finally {
            if (em != null) {
                em.close();
            }
        }
    }
    //Consulta que nos devuelve todos los registros de la tabla.
    public List<Alumno> findAlumnoEntities() {
        return findAlumnoEntities(true, -1, -1);
    }
    //Consulta de página que devuelte los registros de la tabla dentro de cierto rango
    public List<Alumno> findAlumnoEntities(int maxResults, int firstResult) {
        return findAlumnoEntities(false, maxResults, firstResult);
    }
    //Este método es el motor de los dos anteriores.
    private List<Alumno> findAlumnoEntities(boolean all, int maxResults, int firstResult) {
        EntityManager em = getEntityManager();
        try {
            CriteriaQuery cq = em.getCriteriaBuilder().createQuery();
            cq.select(cq.from(Alumno.class));
            Query q = em.createQuery(cq);
            if (!all) {
                q.setMaxResults(maxResults);
                q.setFirstResult(firstResult);
            }
            return q.getResultList();
        } finally {
            em.close();
        }
    }

  
    //Método que funciona como contador de los registros que hay en la tabla.
    public int getAlumnoCount() {
        EntityManager em = getEntityManager();
        try {
            CriteriaQuery cq = em.getCriteriaBuilder().createQuery();
            Root<Alumno> rt = cq.from(Alumno.class);
            cq.select(em.getCriteriaBuilder().count(rt));
            Query q = em.createQuery(cq);
            return ((Long) q.getSingleResult()).intValue();
        } finally {
            em.close();
        }
    }
    
}
